﻿using Navigant.Model.PreservationNotices;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Navigant.Infrastructure.Cases;
using Navigant.Model.Custodians;
using System;
using Navigant.Infrastructure;
using System.Configuration;
using Navigant.Model.Cases;

namespace Navigant.UnitTests
{    
    /// <summary>
    ///This is a test class for PreservationNoticeTest and is intended
    ///to contain all PreservationNoticeTest Unit Tests
    ///</summary>
    [TestClass()]
    public class PreservationNoticeTest
    {
        private TestContext testContextInstance;
        private Uri siteUri;
        private IUnitOfWork unitOfWork;

        public PreservationNoticeTest()
        {
            this.siteUri = new Uri(ConfigurationManager.AppSettings["testCaseSite"]);
            this.unitOfWork = new UnitOfWork();
        }

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        private ICase GetCase()
        {
            return CaseService.GetCaseBy(this.siteUri);
        }

        private Custodian BuildCustodian(ICase parentCase)
        {
            return new Custodian(parentCase,
                new CustodianName("Timothy McCarthy"), "mccarthyis@hotmail.com");
        }

        private PreservationNoticeTemplate BuildTemplate(ICase parentCase)
        {
            return new PreservationNoticeTemplate(parentCase,
                "Test Template", "This is a test template",
                "The message body for test template.  [URL]");
        }


        /// <summary>
        ///A test for MessageVerifiedSent
        ///</summary>
        [TestMethod()]
        public void MessageVerifiedSentTest()
        {
            ICase parentCase = this.GetCase();
            Custodian to = this.BuildCustodian(parentCase);
            PreservationNoticeTemplate template = this.BuildTemplate(parentCase);
            DateTime dateMessageCreated = DateTime.Now;
            PreservationNotice target = template.Merge(to, false, "mccarthyis@hotmail.com");
            DateTime dateMessageSent = DateTime.Now;
            target.MessageVerifiedSent(dateMessageSent);
            Assert.AreEqual(dateMessageSent, target.DateMessageSent);
            Assert.AreEqual(PreservationNoticeStatus.Sent, target.Status);
        }

        /// <summary>
        ///A test for MessageSent
        ///</summary>
        [TestMethod()]
        public void MessageSentTest()
        {
            ICase parentCase = this.GetCase();
            Custodian to = this.BuildCustodian(parentCase);
            PreservationNoticeTemplate template = this.BuildTemplate(parentCase);
            DateTime dateMessageCreated = DateTime.Now;
            PreservationNotice target = template.Merge(to, false, "mccarthyis@hotmail.com");
            target.MessageSent(false);
            Assert.AreEqual(PreservationNoticeStatus.NoticeQueued, target.Status);
        }

        /// <summary>
        ///A test for Acknowledge
        ///</summary>
        [TestMethod()]
        public void AcknowledgeTest()
        {
            // Build the notice
            ICase parentCase = this.GetCase();
            Custodian to = this.BuildCustodian(parentCase);
            PreservationNoticeTemplate template = this.BuildTemplate(parentCase);
            PreservationNotice target = template.Merge(to, false, "mccarthyis@hotmail.com");

            //Acknowledge the notice
            target.Acknowledge();

            // Validate the notice and the custodian
            Assert.AreEqual(PreservationNoticeStatus.Acknowledged, target.Status);
            Assert.IsTrue(target.DateMessageAcknowledged.HasValue);
            Assert.AreEqual(target.DateMessageCreated, target.DateMessageSent.Value);
            Assert.AreEqual(PreservationNoticeStatus.Acknowledged, target.To.Status);
            Assert.AreEqual(target.DateMessageCreated.ToString(), target.To.ExtendedProperties["PN-Sent"]);
        }

        /// <summary>
        ///A test for Acknowledge
        ///</summary>
        [TestMethod()]
        public void AcknowledgeAndSaveTest()
        {
            // Build the notice
            ICase parentCase = this.GetCase();
            Custodian to = this.BuildCustodian(parentCase);
            PreservationNoticeTemplate template = this.BuildTemplate(parentCase);
            PreservationNotice target = template.Merge(to, false, "mccarthyis@hotmail.com");

            //Acknowledge the notice
            target.Acknowledge();

            // Save the notice
            PreservationNoticeService service = new PreservationNoticeService(parentCase, this.unitOfWork);
            service.SavePreservationNotice(target);
            this.unitOfWork.Commit();

            // Find the notice and validate that the acknowledgement date is populated
            PreservationNotice notice = service.FindBySiteAnd(target.MessageIdentifier)[0];
            Assert.IsTrue(notice.DateMessageAcknowledged.HasValue);
        }
    }
}
